package gui.catalogues.persons;

import gui.catalogues.telephones.interfaces.TelephonesTableListener;
import gui.catalogues.telephones.models.TelephonesDialog;
import gui.catalogues.telephones.models.TelephonesTablePanel;
import gui.commons.CommonLayoutOperations;
import gui.commons.IdText;
import gui.commons.ToolbarListener;
import gui.mainframe.MainFrame;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;

import org.apache.log4j.Logger;

import controller.PersonController;

public class PersonFormPanel extends JPanel {
	/*
	 * logger
	 */
	private final static Logger logger = Logger.getLogger(MainFrame.class);
	
	/*
	 * Field variables declaration
	 */
	private JLabel name;
	private ToolbarListener sl;
	private Border innerBorder = BorderFactory
			.createTitledBorder("ABC Personas"), outerBorder = BorderFactory
			.createEmptyBorder(5, 5, 5, 5);
	private Border compoundBorder = BorderFactory.createCompoundBorder(
			outerBorder, innerBorder);
	Dimension dim = getPreferredSize();
	// private JLabel name, surname;
	private JTextField tfName, tfSurname, tfDir, tfCol, tfCP, tfImg1, tfImg2,
			tfImg3, tfRef1, tfRef2;
	private JList jlTels, jlMails;
	private JButton ok, btDelTA;
	JPanel jpTelephonesControls, jpEmailsControls;

	/*
	 * layout variables declaration
	 */
	private int y;
	private GridBagConstraints gc;
	private Insets lblInset, tfInset, btnInset;

	/*
	 * Repetitive tasks class variable
	 */
	private CommonLayoutOperations cOps;

	/*
	 * PersonFormPanel variables
	 */
	private PersonFormListener fl;
	private DefaultComboBoxModel<IdText> dmCollateralClient;
	private JComboBox<IdText> cbCollateralClient;
	private JCheckBox chDirectClient, chIndirectClient, chBizPartner,
			chServiceProvider;
	private boolean boolIcChecked, boolDcChecked;

	/*
	 * field variables
	 */
	private JButton btImg1, btImg2, btImg3, btTelephonesDialog, btEmailsDialog;
	private JFileChooser fc;// Img1, fcImg2, fcImg3;
	private JPanel jpImg1, jpImg2, jpImg3;

	/*
	 * Telephones dialog
	 */
	TelephonesDialog telsDiag;
	TelephonesTablePanel ttpTelephones;
	
	/*
	 * controllers
	 * */
	PersonController personController;

	public PersonFormPanel() {

		/*
		 * Initializers and population
		 */
		initAndPopulate();

		/*
		 * Generate the panel's layout
		 */
		manageLayout();

		/*
		 * ActionListeners
		 */
		manageListeners();
	}

	public void initAndPopulate() {
		/*
		 * Initializing variables
		 */

		/*
		 * layout variables
		 */
		gc = new GridBagConstraints();
		lblInset = new Insets(0, 0, 0, 1);
		tfInset = new Insets(0, 1, 0, 1);
		btnInset = new Insets(1, 1, 1, 1);

		/*
		 * Common tasks variable
		 */
		cOps = new CommonLayoutOperations(lblInset, tfInset, btnInset);

		/*
		 * Field variables
		 */
		name = new JLabel("Nombre: ");
		// name label mnemonics
		name.setDisplayedMnemonic(KeyEvent.VK_M);

		tfName = new JTextField(2);
		// pressing my label mnemonic will get the cursor to my name textfield
		name.setLabelFor(tfName);

		tfSurname = new JTextField(2);
		tfDir = new JTextField(3);
		tfCol = new JTextField(1);
		tfCP = new JTextField(1);
		tfImg1 = new JTextField(3);
		tfImg2 = new JTextField(3);
		tfImg3 = new JTextField(3);
		tfRef1 = new JTextField(2);
		tfRef2 = new JTextField(2);
		ok = new JButton("Agregar");
		// btDelTA = new JButton("Limpiar");

//		jlMails = new JList();
//		jlTels = new JList();

		/*
		 * ProductFormPanel only initializers
		 */
		cbCollateralClient = new JComboBox();
		dmCollateralClient = new DefaultComboBoxModel();
		chDirectClient = new JCheckBox("Cliente directo.");
		chIndirectClient = new JCheckBox("Cliente indirecto: ");
		chServiceProvider = new JCheckBox("Proveedor: ");

		// ok button mnemonics
		ok.setMnemonic(KeyEvent.VK_T);

		/*
		 * I populate the default model for my dmCollateralClient and set it in
		 * the latter
		 */
		dmCollateralClient.addElement(new IdText(0, "-Escoja uno-"));
		dmCollateralClient.addElement(new IdText(1,
				"Pedro Pérez (Revista Maxwell)"));
		dmCollateralClient.addElement(new IdText(2, "Alejandro Alcaide"));
		dmCollateralClient.addElement(new IdText(3, "Juan Pérez"));

		cbCollateralClient.setModel(dmCollateralClient);

		/*
		 * fileChoosers for the person's images
		 */
		fc = new JFileChooser();
		// .per filter
		// fc.addChoosableFileFilter(new PersonFileFilter());
		fc.setFileFilter(new PersonFileFilter());
		jpImg1 = new JPanel();
		jpImg2 = new JPanel();
		jpImg3 = new JPanel();
		btImg1 = new JButton("Examinar");
		btImg2 = new JButton("Examinar");
		btImg3 = new JButton("Examinar");

		/*
		 * Telephones dialog
		 */
		jpTelephonesControls = new JPanel();
		ttpTelephones = new TelephonesTablePanel();
		btTelephonesDialog = new JButton("Editar");
		telsDiag = new TelephonesDialog(
				((JFrame) SwingUtilities.getWindowAncestor(this)),
				"ABC Teléfonos", true);
		/*
		 * Emails dialog
		 */
		jpEmailsControls = new JPanel();
		btEmailsDialog = new JButton("Editar");
		
		/*
		 * controllers
		 * */
		personController = new PersonController();
	}

	public void manageLayout() {
		/*
		 * setting size and borders for the Panel
		 */
		dim.height = 400;
		dim.width = 750;
		setPreferredSize(dim);
		// setMinimumSize(new Dimension(dim.width - 15, dim.height));
		setMinimumSize(dim);
		setBorder(compoundBorder);

		/*
		 * Manage Layout
		 */
		setLayout(new GridBagLayout());

		// position x, y
		gc.gridx = 0;
		gc.gridy = 0;
		// padding (minimum space left between component and enclosing cell
		gc.ipadx = 5;
		gc.ipady = 3;
		// space relative to other cells around
		gc.weightx = 0.5;
		gc.weighty = 0.1;
		// Take or not the space left in the layout
		gc.fill = GridBagConstraints.NONE;

		/*
		 * Populate the grid with its components
		 */

		y = 0;
		/*
		 * this first label uses an instantiated variable because I'm using
		 * mnemonics that need it to work
		 */
		cOps.addLabel(this, name, 0, y);
		cOps.addTextField(this, tfName, 1, y);
		cOps.addJLabel(this, "Apellidos: ", 2, y);
		cOps.addTextField(this, tfSurname, 3, y);
		y++; // 2
		cOps.addJLabel(this, "Dirección: ", 0, y);
		cOps.addTextField(this, tfDir, 1, y);
		cOps.addJLabel(this, "Colonia: ", 2, y);
		cOps.addTextField(this, tfCol, 3, y);
		y++; // 4
		jpTelephonesControls.setLayout(new BorderLayout());
		// jpTelephonesControls.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,
		// Color.black, Color.green));
		// jpTelephonesControls.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		jpTelephonesControls.setSize(new Dimension(125, 125));
		jpTelephonesControls
				.add(new JLabel("Teléfonos: "), BorderLayout.CENTER);
		jpTelephonesControls.add(btTelephonesDialog, BorderLayout.SOUTH);
		cOps.addJPanel(this, jpTelephonesControls, 0, y);
		cOps.addJPanel(this, ttpTelephones, 1, y);

		jpEmailsControls.setLayout(new BorderLayout());
		jpEmailsControls.setSize(new Dimension(125, 125));
		jpEmailsControls.add(new JLabel("E-mails: "), BorderLayout.CENTER);
		jpEmailsControls.add(btEmailsDialog, BorderLayout.SOUTH);
		cOps.addJPanel(this, jpEmailsControls, 2, y);
		// cOps.addJLabel(this, "E-mail: ", 2, y);
		//cOps.addJList(this, jlMails, 3, y);
		y++; // 5
		cOps.addJLabel(this, "Código Postal: ", 0, y);
		cOps.addTextField(this, tfCP, 1, y);

		y++; // 7
		cOps.addJLabel(this, "Referencia 1: ", 0, y);
		cOps.addTextField(this, tfRef1, 1, y);
		cOps.addJLabel(this, "Referencia 2: ", 2, y);
		cOps.addTextField(this, tfRef2, 3, y);
		y++; // 9
		cOps.addJLabel(this, "IFE frente: ", 0, y);
		jpImg1.setLayout(new FlowLayout(FlowLayout.LEADING));
		jpImg1.add(tfImg1);
		jpImg1.add(btImg1);
		cOps.addJPanel(this, jpImg1, 1, y);
		cOps.addJLabel(this, "IFE detrás: ", 2, y);
		cOps.addTextField(this, tfImg2, 3, y);
		cOps.addJButton(this, btImg2, 4, y);
		y++; // 11
		cOps.addJLabel(this, "Comprobante: ", 0, y);
		cOps.addTextField(this, tfImg3, 1, y);
		cOps.addJButton(this, btImg3, 2, y);
		// y++; // 12
		// cOps.addJCheckBox(this, chDirectClient, 0, y);
		// y++; // 13
		// cOps.addJCheckBox(this, chIndirectClient, 0, y);
		// cOps.addJComboBox(this, cbCollateralClient, false, 1, y);
		// y++; // 14
		// cOps.addJCheckBox(this, chServiceProvider, 0, y);
		// System.out.println(tfImg3.getMinimumSize() + ", " +
		// tfImg3.getPreferredSize());
		y++; // last
		cOps.addJButton(this, ok, 1, y);
		// cOps.addJButton(this, btTelephonesDialog, 0, y);
		// cOps.addJButton(this, btDelTA, 3, y);
		
		/*
		 * Initially, the personForm's fields are edit-disabled
		 * */
		enablePersonFields(false);
	}

	public void manageListeners() {
		ok.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				PersonDTO pfe = new PersonDTO(e, tfName.getText(), tfSurname
						.getText(), (IdText) cbCollateralClient
						.getSelectedItem(), chIndirectClient.isSelected());
				if (fl != null) {
					fl.PersonFormEventOccured(pfe);
				}
			}
		});

		btTelephonesDialog.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				logger.info("'TelephonesDialog' opening");
				//System.out.println("Dialog opening - TelephonesDialog.");
				//personController.addEmptyPerson();
				telsDiag.setVisible(true);
			}
		});

		/*
		 * This listener starts with the comboBox off and awaits for the
		 * checkBox to be selected so the comboBox can be activated to choose a
		 * collateral. In reverse, it takes the list to the first -default- item
		 * and deactivates the comboBox again.
		 */
		chIndirectClient.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (chIndirectClient.isSelected()) {
					chDirectClient.setSelected(false);
					cbCollateralClient.setEnabled(true);
				} else if (!chIndirectClient.isSelected()) {
					cbCollateralClient.setSelectedIndex(0);
					cbCollateralClient.setEnabled(false);
				}
			}
		});

		/*
		 * This listener starts with the comboBox off and awaits for the
		 * checkBox to be selected. If so, it checks if the chIndirectClient
		 * checkbox is checked, unchecks it and disables the the
		 * cbCollateralClient comboBox, returning it to the first default
		 * selection.
		 */
		chDirectClient.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (chDirectClient.isSelected()) {
					chIndirectClient.setSelected(false);
					cbCollateralClient.setSelectedIndex(0);
					cbCollateralClient.setEnabled(false);
				}
			}
		});

		/*
		 * btImport button
		 * 
		 * if I want to open a saving dialog instead of an opening one, I could
		 * use showSaveDialog instead of showOpenDialog
		 */
		btImg1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (fc.showOpenDialog(PersonFormPanel.this) == JFileChooser.APPROVE_OPTION) {
					tfImg1.setText(String.valueOf(fc.getSelectedFile()));
				}
			}
		});

		/*
		 * ActionListener to manage the right mouse click over the table
		 */
		// ttpTelephones.addMouseListener(new MouseAdapter() {
		// @Override
		// public void mousePressed(MouseEvent e) {
		// // if the mouse button is the right one...
		// if (e.getButton() == MouseEvent.BUTTON3) {
		// System.out.println("Pressed right click on the TelephoneTypesPanel");
		// telsDiag.setVisible(true);
		// }
		// }
		// });
//		ttpTelephones.setTelephonesTableListener(new TelephonesTableListener() {
//
//			@Override
//			public void mouseClicked(MouseEvent e) {
//				// if the mouse button is the right one...
//				if (e.getButton() == MouseEvent.BUTTON3) {
//					System.out
//							.println("Pressed right click on the TelephoneTypesPanel");
//					telsDiag.setVisible(true);
//				}
//			}
//		});
	}
	
	/*
	 * This method would be called whenever the user wants to add a new row
	 * */
	public void setFieldsBlank() {
//		private JTextField tfName, tfSurname, tfDir, tfCol, tfCP, tfImg1, tfImg2,
//		tfImg3, tfRef1, tfRef2;
		tfName.setText("");
		tfSurname.setText("");
		tfDir.setText("");
		tfCol.setText("");
		tfCP.setText("");
	}
	
	/*
	 * This method will maintain the personForm's textfields disabled until a 'New' or 'Edit' operation is requested
	 * */
	public void enablePersonFields(boolean b) {
		tfName.setEditable(b);
		tfSurname.setEditable(b);
		tfDir.setEnabled(b);
		tfCol.setEditable(b);
		tfCP.setEditable(b);
	}

	// method to assign a textPanel to the formPanel so the latter will be
	// listened
	public void setStringListener(ToolbarListener sl) {
		this.sl = sl;
	}

	
	public void setPersonFormListener(PersonFormListener fl) {
		this.fl = fl;
	}
}